package org.example.filter;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.micrometer.common.util.StringUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.example.entity.MyUserDetails;
import org.example.util.JwtUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;


@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if ("/login".equals(request.getRequestURI())) {
            filterChain.doFilter(request, response);
            return;
        }
        // 非登录请求要经过验证
        // 获取token密文
        String accessToken = request.getHeader("access_token");
        if (StringUtils.isEmpty(accessToken)) {
            throw new BadCredentialsException("access_token 为空");
        }
        //token明文
        Claims claims = null;
        try {
            claims = JwtUtil.parseToken(accessToken);
        }catch (ExpiredJwtException e1){
            throw new BadCredentialsException("access_token 过期了");
        } catch (Exception e) {
            throw new BadCredentialsException("access_token 无效");
        }
        String subject = claims.getSubject();
        // 获取用户
        Object o = redisTemplate.opsForValue().get(subject);
        if(o==null){
            throw new BadCredentialsException("用户过期了");
        }
        MyUserDetails myUserDetails = (MyUserDetails) o;

        // 用户信息放入安全上下文中
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(myUserDetails, null, myUserDetails.getAuthorities());

        SecurityContextHolder.getContext().setAuthentication(authenticationToken);

        //之后放行
        filterChain.doFilter(request, response);
    }

    public static void main(String[] args) {
        Claims claims = JwtUtil.parseToken("1eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJlODU4YzAxZC1iN2Q5LTQ1MTMtYTljOC03NDA3NGRkMzYzMjMiLCJpc3MiOiJsYW9saSIsImlhdCI6MTc1NDEzMTc0OSwiZXhwIjoxNzU0MTMyMDQ5LCJzdWIiOiJ1c2VyOjEifQ.AA4GgIkDm1HIMQRa1Tkauad2l0RrFpNeahluDrmc9IQ");
        System.out.println(claims);
    }
}
